<template>
  <div :class="containerClass">
    <div
      v-for="(item, index) in timelineItems"
      :key="item.id"
      class="timeline-item"
    >
      <div
        class="timeline-node"
        :class="[`is-${item.type}`, size]"
        :style="nodeStyle"
      >
        <i v-if="icon" :class="icon"></i>
        <slot name="dot" v-else></slot>
      </div>
      <div
        class="timeline-line"
        :class="{
          'is-first': index === 0,
          'is-last': index === timelineItems.length - 1,
          'is-horizontal': props.direction === 'horizontal',
          'is-arrive': item.isArrive,
        }"
      ></div>
      <div class="timeline-content">
        <div class="timeline-content-inner">
          <slot>{{ item.content }}</slot>
        </div>
        <div class="timeline-timestamp">
          <slot>{{ item.timestamp }}</slot>
        </div>
      </div>
    </div>
  </div>
</template>


<script setup>
import { ref, computed } from "vue";

const props = defineProps({
  direction: {
    type: String,
    default: "vertical",
    validator: (value) => ["vertical", "horizontal"].includes(value),
  },
  reverse: {
    type: Boolean,
    default: false,
  },
  timestamp: {
    type: String,
    required: true,
  },
  type: {
    type: String,
    default: "primary",
    validator: (value) =>
      ["primary", "success", "warning", "danger", "info"].includes(value),
  },
  color: {
    type: String,
    validator: (value) => /^(#|rgb|hsl|hsv)/.test(value),
  },
  size: {
    type: String,
    default: "normal",
    validator: (value) => ["normal", "large"].includes(value),
  },
  icon: {
    type: String,
    default: "",
  },
  timelineItems: {
    type: Array,
  },
});

// const timelineItems = ref([
//   { id: 1, timestamp: "2024-01-01", content: "项目启动", type: "primary" },
//   { id: 2, timestamp: "2024-02-15", content: "开发阶段", type: "warning" },
//   { id: 3, timestamp: "2024-03-20", content: "测试完成", type: "success" },
//   { id: 4, timestamp: "2024-04-10", content: "正式发布", type: "info" },
// ]);

const nodeStyle = computed(() => {
  const style = {};
  if (props.color) {
    style.backgroundColor = props.color;
  }
  if (props.size === "large") {
    style.width = "16px";
    style.height = "16px";
  }
  return style;
});

const containerClass = computed(() => ({
  "timeline-container": true,
  "is-horizontal": props.direction === "horizontal",
  "is-reverse": props.reverse,
}));
</script>



<style scoped>
.timeline-container {
  position: relative;
  /* padding: 20px 0; */
}

.timeline-item {
  position: relative;
  display: flex;
  margin-bottom: 20px;
}

.timeline-line {
  position: absolute;
  background-color: #e4e8ec;
  z-index: 1;
}
.is-arrive {
  background-color: #ff9c22;
}
.timeline-line:not(.is-horizontal) {
  left: 5px;
  top: -10px;
  width: 2px;
  height: calc(100% + 20px);
}

.large + .timeline-line:not(.is-horizontal) {
  left: 7px;
}

.timeline-line.is-horizontal {
  left: 0;
  top: 5px;
  width: 100%;
  height: 2px;
}

.timeline-line.is-first:not(.is-horizontal) {
  top: 0;
}

.timeline-line.is-horizontal.is-first {
  left: 0;
}

.timeline-line.is-last:not(.is-horizontal) {
  height: calc(50% - 10px);
  transform: translateY(-50%);
}

.timeline-line.is-horizontal.is-last {
  width: 50%;
  transform: translateX(-100%);
}

.timeline-node {
  position: relative;
  z-index: 2;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: #ff9c22;
  flex-shrink: 0;
  margin-right: 16px;
}

.timeline-node.large {
  width: 16px;
  height: 16px;
}

.timeline-node.is-primary {
  border: 2px solid #ff9c22;
  background-color: #fff;
}
.timeline-node.is-success {
  border: 2px solid #67c23a;
  background-color: #fff;
}
.timeline-node.is-warning {
  border: 2px solid #e6a23c;
  background-color: #fff;
}
.timeline-node.is-danger {
  border: 2px solid #f56c6c;
  background-color: #fff;
}
.timeline-node.is-info {
  border: 2px solid #c9cdd4;
  background-color: #fff;
}

.timeline-content {
  flex: 1;
  /* padding: 0 16px; */
}

.timeline-timestamp {
  font-size: 0.24rem;
  color: #999999;
  /* margin-bottom: 8px; */
}

.timeline-content-inner {
  /* background-color: #f5f7fa; */
  color: #333;
  font-size: 0.28rem;
  padding: 10px 0 6px;
  /* border-radius: 4px; */
}

.is-horizontal {
  display: flex;
  justify-content: space-between;
}

.is-horizontal .timeline-item {
  flex-direction: column;
  /* flex: 1; */
  padding-right: 20px;
  margin-bottom: 0;
  flex-shrink: 0;
  width: 2.35rem;
}
/* .is-horizontal .timeline-item:last-child {
  width: 1.1rem !important;
  max-width: 2.35rem;
} */
.is-reverse {
  flex-direction: row-reverse;
}

.is-reverse .timeline-item {
  flex-direction: column-reverse;
}
</style>
